package ru.spbau.database.group3.filesAndAccess;

import ru.spbau.database.group3.engine.Column;
import ru.spbau.database.group3.engine.Condition;
import ru.spbau.database.group3.engine.DatabaseEngine;
import ru.spbau.database.group3.engine.Relation;
import ru.spbau.database.group3.memoryManager.SpaceManager;

import java.io.IOException;
import java.io.Serializable;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * User: stels
 * Date: 09.02.13
 * Time: 12:17
 */
public class HeapFile implements Serializable {

    public HeapFile(String path, List<Column> columns, LinkedList<Integer> freePages, LinkedList<Integer> fullPages) {
        this.path = path;
        this.columns = columns;
        this.freePages = freePages;
        this.fullPages = fullPages;
    }

//    public Collection<Record> selectRecordsFromIndex(Index index, Condition c) throws IOException {
//    	ArrayList<Record> records = new ArrayList<Record>();
//    	Collection<Integer> relevantPages = index.getPages(c);
//    	for (Integer pageNum : relevantPages) {
//    		Page p = new Page(pageNum);
//    		records.addAll(p.getRecords(c));
//    	}
//    	return records;
//    }
    
//    public Collection<Record> selectRecordsFromIndex(Index index, Collection<Condition> conditions) throws IOException {
//    	ArrayList<Record> records = new ArrayList<Record>();
//    	Collection<Integer> relevantPages = index.getPages(conditions);
//    	for (Integer pageNum : relevantPages) {
//    		Page p = new Page(pageNum);
//    		records.addAll(p.getRecords(conditions));
//    	}
//    	return records;
//    }
    
    public List<Record> selectRecords(List<Condition> c) throws IOException {
        List<Record> records = new ArrayList<Record>();
        for(int i : fullPages) {
            Page p = new Page(i);
            records.addAll(p.getRecords(c)) ;
        }
        for(int i : freePages) {
            Page p = new Page(i);
            records.addAll(p.getRecords(c));
        }
        return records;
    }

    public List<Record> deleteRecords(List<Condition> c) throws IOException {
        List<Record> records = new ArrayList<Record>();
        for(int i : fullPages) {
            Page p = new Page(i);
            records.addAll(p.deleteRecords(c));
        }
        for(int i : freePages) {
            Page p = new Page(i);
            records.addAll(p.deleteRecords(c));
        }
        return records;
    }


    public Record insertRecord(ByteBuffer data) throws IOException {
        if(freePages.size() > 0) {
            return insertRecord(new Page(freePages.pop()), data);
        }
        Page p = SpaceManager.allocPage(path + "HeapFile" + Relation.DATA_EXT, DatabaseEngine.calculateRecordSize(columns));
        return insertRecord(p, data);
    }

    

    private Record insertRecord(Page p, ByteBuffer recordData) throws IOException {
        Record r = p.insertRecord(recordData);
        join(p);
        return r;
    }

    private void join(Page p) throws IOException {
        if(p.isFull()) {
            fullPages.addFirst(p.getId());
        } else {
            freePages.addFirst(p.getId());
        }
    }




    private final String path;
    private List<Column> columns;

    private LinkedList<Integer> freePages;
    private LinkedList<Integer> fullPages;


}
